/**
 * @class 阅读基础类
 * @description 定义实现基础功能
 * @constructor
 */
import BaseContext from "../../context";
export default class ReadMode extends BaseContext {
  constructor(app, options) {
    super(app, options);
    this.maxWidth = options.maxWidth || 800;
    this.api = Object.assign({ getChapterInfo: `/api/getchapterinfov2` }, options.api)
    this.init();
  }

  get scrollBox() {
    return this.scrollContainer.querySelector('.reader-chapter__scroll-box');
  }

  // 初始化内部数据
  initState() {
    // 实时滚动信息
    this.scrollInfo = {
      direction: 0, // 滚动方向 正值向下滚动，负值向上滚动
      scrollHeight: 0,
      scrollTop: 0
    };

    this.distance = this.options.distance || 100;
    this.checkTemplate();
    this.createContainer();
    this.chapterIdQueue = []; // 用来存储章节id队列，便于后面在dom中选取删除不在队列中的数据
  }

  init() {
    this.initState();
    this.initListener()
    this.initEvent();
    this.initTargetEvent();
  }

  initEvent() {
    const container = this.container;
    this.util.addEventListener(container, 'touchstart', e => this.emit('onTouchStart', e))
    this.util.addEventListener(container, 'touchmove', e => this.emit('onTouchMove', e))
    this.util.addEventListener(container, 'touchend', e => this.emit('onTouchEnd', e))
    this.util.addEventListener(container, 'click', e => this.emit('clickContainer', e))
    this.util.addEventListener(this.scrollContainer, 'scroll', e => this.scrollHanddle(e))
  }

  initTargetEvent() {
    const container = this.container;
    this.util.addEventListener(container, 'click', this.imageErrorHanddle.bind(this));
  }

  scrollHanddle({ target }) {
    const { scrollTop, scrollHeight, offsetHeight } = target;
    let { scrollTop: oldScrollTop, scrollHeight: oldScrollHeight } = this.scrollInfo;
    let { distance } = this;
    const direction = scrollTop - oldScrollTop
    this.scrollInfo.scrollTop = scrollTop;
    this.scrollInfo.direction = direction;
    this.scrollInfo.scrollHeight = scrollHeight;
    this.emit('scrollChapter');
    if (scrollTop + offsetHeight + distance > scrollHeight && direction > 0) {
      this.emit('scrollLoadChapter', 'next');
    } else if (scrollTop - distance < 0 && direction < 0) {
      this.emit('scrollLoadChapter', 'prev');
    }

    // 解决极限上拉时，scrollTop为0导致定位出现问题
    if (scrollTop === 0 && scrollHeight >= oldScrollHeight) {
      setTimeout(() => {
        this.scrollContainer.scrollTop = this.scrollContainer.scrollHeight - oldScrollHeight;
      }, 17);
    }
  }

  // 检查是否配置模板
  checkTemplate() {
    const template = this.template;
    if (template.container && template.chapterContainer && template.imageContainer) {
      return template;
    }
    const msg = '阅读器初始化失败，缺少必要的container,chapterContainer,imageContainer模板'
    this.logger.error(msg);
    throw new Error(msg);
  }

  initListener() {
    this.listener({
      intersectingTargets: this.intersectingTargets.bind(this),
      initLoadChapterHtml: this.initLoadChapterHtml.bind(this),
      scrollLoadChapter: this.scrollLoadChapter.bind(this),
      loadImageFinish: this.loadImageFinish.bind(this),
    })
  }

  // 填充一张图片的最大高宽（m端，pc竖屏为屏幕高宽，pc横屏为双页中的一页高宽）
  get containerSize() {
    const { width, height } = this.util.viewSize();
    const { offsetWidth, offsetHeight } = this.container;
    return {
      width: Math.min(offsetWidth, width),
      height: Math.min(offsetHeight, height)
    }
  }

  /**
   * @function hasCopyrightAndShowInfo 是否有版权信息，并进行标记处理
   * @return {boolean} true|false
   */
  get hasCopyright() {
    return this.comicInfo.hasCopyright;
  }

  intersectingTargets(targets) {
    const { height } = this.containerSize;
    targets.forEach(({ target, chapterId, chapterIndex }) => {
      const top = this.scrollInfo.scrollTop + height / 2 - target.offsetTop;
      // 如果大于0说明过中线，且不能大于自身高度
      if (top > 0 && top < target.offsetHeight) {
        this.comicInfo.setCurrentChapterId(chapterId);
        this.emit(['chapterChange', 'chapterIndexChange'], [null, chapterIndex]);
      }
    })
  }

  initLoadChapterHtml() {
    if (this.hasCopyright) {
      const chapter = this.currentChapter;
      this.emit(['chapterChange', 'chapterIndexChange']);
      return this.installChapterHTML(chapter);
    }
    this.copyrightHtml(this.comicInfo);
  }

  scrollLoadChapter(flag = 'next') {
    const { currentChapterId, chapterMap } = this.comicInfo;
    const currentChapter = this.currentChapter;
    const nextOrPrevChapterId = flag === 'next' ? currentChapter.nextChapterId : currentChapter.prevChapterId;
    // 不存章节id返回并执行请求
    if (!nextOrPrevChapterId) {
      return;
    }
    const nextOrPrevChapter = chapterMap[nextOrPrevChapterId];
    const { chapterId, prevChapterId, nextChapterId } = nextOrPrevChapter;
    // 存在章节信息，且章节id和当前章节相同
    if (currentChapterId === chapterId) {
      return;
    }
    if (this.chapterIdQueue.indexOf(nextOrPrevChapterId) === -1) {
      this.chapterIdQueue[flag === 'next' ? 'push' : 'unshift'](nextOrPrevChapterId);
    }
    const hasChapterId = flag === 'next' ? nextChapterId : prevChapterId;
    if (!hasChapterId) {
      console.log('====>发送请求')
      this.emit('loadChapter', chapterId)
    }
    this.installChapterHTML(nextOrPrevChapter);
  }

  loadImageFinish(image) {
    // 图片完成,附带完成状态: init, loading, loaded, error, timeout
    let { target, status, isRetry } = image;
    if (status === 'loaded') {
      if (isRetry) {
        target.innerHTML = this.installChapterItemHTML(image);
        image.isRetry = false;
      }
      this.setChapterItemDOM(image);
    } else if (['error', 'timeout'].indexOf(status) > -1) {
      this.errorRepyHtml(target, image);
    }
  }

  setChapterItemDOM(image) {
    let { target, width, height, src } = image;
    const chapterImg = target.querySelector('.chapter-img');
    const loadingTips = target.querySelector('.loading-tip');
    // loadingTips.style.display = 'none';

    // 获取追加前的高度
    const size = this.containerSize;
    const maxWidth = Math.min(size.width, this.maxWidth);
    const scale = maxWidth / width;
    width = Math.min(width, maxWidth);
    // height = 200; 这是测试
    height = height * scale;

    target.style.width = width + 'px';
    target.style.height = height + 'px';

    chapterImg.src = src;
    chapterImg.style.width = width + 'px';
    chapterImg.style.height = height + 'px';
    chapterImg.style.opacity = 1;

    // 这里很关键，只有上拉才重新设置scrollTop
    const { scrollTop, direction } = this.scrollInfo;
    if (direction < 0) {
      const diffHeight = height - size.height;
      this.scrollContainer.scrollTop = scrollTop + diffHeight;
    }
  }

  errorRepyHtml(target, image) {
    const template = this.template;
    let errorMsg = target.querySelector('.tip-error-msg');
    if (template.errorReply && !errorMsg) {
      const { chapterName } = this.currentChapter;
      target.innerHTML = template.errorReply({
        comicName: this.comicInfo.comicName,
        chapterName,
        ...image
      });
      errorMsg = target.querySelector('.tip-error-msg');
      errorMsg.style.opacity = 1;
    }
  }

  copyrightHtml(comicData) {
    const template = this.template;
    if (template.copyrightContainer) {
      const nodes = template.copyrightContainer({
        message: `《${comicData.comicName}》<br>该漫画我们正在努力争取版权，敬请期待`,
        alt: comicData.comicName,
        src: this.util.switchWebp(comicData.coverCDN('c3r4'))
      });
      this.scrollContainer.innerHTML = nodes;
      return;
    }
    this.logger.error('缺少版权信息模板');
  }

  createContainer() {
    const dom = this.util.createDocumentHtml(this.template.container);
    this.container.appendChild(dom);
    this.app.scrollContainer = this.container.querySelector('#reader-scroll');
  }

  installChapterItemHTML(data) {
    const template = this.template;
    return template.imageContainer({
      ...data,
      ...this.containerSize,
    })
  }

  installChapterHTML(chapter) {
    const template = this.template;
    const { chapterName, chapterId } = chapter;
    const { chapterList } = this.comicInfo.chapterMap[chapterId];

    let imageItems = '';
    chapterList.forEach(item => {
      imageItems += this.installChapterItemHTML(item);
    });

    const chapterContainer = template.chapterContainer({
      chapterId,
      chapterName,
      slot: imageItems
    });
    const chapterNodes = this.util.createDocumentHtml(chapterContainer);
    this.installChapterNodes(chapterNodes, this.scrollInfo);
    const ListNodes = this.getInsertNodes(chapterId);
    this.emit('startImageObserver', ListNodes);
  }

  getInsertNodes(chapterId) {
    return this.scrollContainer.querySelectorAll(`.reader-chapter__item[data-chapter-id="${chapterId}"]`)
  }

  installChapterNodes(chapterNodes, { direction }) {
    this.logger.time('追加内容')
    this.scrollBox[direction >= 0 ? 'append' : 'prepend'](chapterNodes);
    this.logger.timeEnd('追加内容')
  }

  imageErrorHanddle(event) {
    const { target } = event;
    const { chapterIndex } = this.util.getChapterDataset(target);
    if (chapterIndex) {
      const { chapterList } = this.currentChapter;
      const image = chapterList[chapterIndex - 1];

      // 这里是测试，将图片地址搞错后恢复
      // image.src = image.src.replace('@@', '')

      // 将图片是否重试置为true，以便后面加载成功后将图片插入dom作判断。
      image.isRetry = true;
      this.emit('loadImages', [image]);
    }
  }
}
